package com.ljf.framework.util;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 说明：
 *
 * @Auther: lijinfeng
 * @Date: 2023/9/20
 */
public class LjfJsonUtil {

    private static char objectBegin = '{';

    private static char objectEnd = '}';

    private static char delimiter = ',';

    private static char arrayBegin = '[';

    private static char arrayEnd = ']';

    private static char quote = '"';

    private static char colon = ':'; // 冒号


    /**
     * 字符转成大写
     *
     * @param c 需要转化的字符
     */
    public static char toUpperCase(char c) {
        if (97 <= c && c <= 122) {
            c ^= 32;
        }
        return c;
    }

    public static <T> T fromJsonStringSimple(Class<T> clzz, String jsonString) throws Exception {
        T t = clzz.newInstance();

        String replace = jsonString.replace("{", "").replace("}","");
        String[] kvs = replace.split(",");
        for (String kv : kvs){
            String[] split = kv.split(":");
            String key = split[0].replace("\"","").trim();
            String value = split[1].replace("\"","").trim();
            Field field = clzz.getDeclaredField(key);
            field.setAccessible(true);
            field.set(t,value);
        }
        return t;
    }


    /**
     * 将一个json字符串转成一个Object
     * **/
    public static <T> T fromJsonString(Class<T> clzz, String jsonString) throws Exception {
        // 原始类型
        if (isPrimitive(clzz)) {
            // 原始类型或, 那么认为只可能是 数字 或 boolean
            if (isNumeric(jsonString)) return (T) Integer.valueOf(jsonString);
            return (T) Boolean.valueOf(jsonString);
        }
        // 字符串
        if (String.class.equals(clzz)) {
            // 去掉首尾的"
            return (T) jsonString.substring(1, jsonString.length() - 1);
        }

        // 集合类型
        if (Collection.class.isAssignableFrom(clzz)) {
            // 暂不支持
            return null;
        }

        // 普通 POJO
        Object ret = clzz.newInstance();
        StringBuilder sb = new StringBuilder(jsonString);
        while (sb.charAt(sb.length() - 1) == ' ') sb.deleteCharAt(sb.length() - 1);
        if (sb.charAt(sb.length() - 1) == objectEnd) sb.deleteCharAt(sb.length() - 1);
        jsonString = sb.toString();

        int n = jsonString.length();
        int i = 0;
        while (i < n) {
            while (jsonString.charAt(i) != quote) i++;
            int pBegin = ++i;
            while (jsonString.charAt(i) != quote) i++;
            int pEnd = i;
            while (jsonString.charAt(i) != colon) i++;
            i++; // 移动到冒号后一个字符
            while (jsonString.charAt(i) == ' ') i++; // 跳过空格
            // 属性开始
            int vBegin = i;
            Deque<Character> stack = new LinkedList<>();
            while (true) {
                while (i < jsonString.length() && jsonString.charAt(i) == ' ') {
                    i++;
                }

                if (i >= jsonString.length()) break;

                if (jsonString.charAt(i) == objectBegin) {
                    stack.push(objectBegin);
                    i++;
                } else if (jsonString.charAt(i) == objectEnd) {
                    stack.pop();
                    i++;
                } else i++;

                if ((i == jsonString.length() || jsonString.charAt(i) == delimiter) && stack.isEmpty()) {
                    break;
                }

            }
            int vEnd = i; // 此时 i 的位置是 , 或者末尾

            String propertyName = jsonString.substring(pBegin, pEnd);

            String valueJsonString = jsonString.substring(vBegin, vEnd);

            Field f = clzz.getDeclaredField(propertyName);
            f.setAccessible(true);
            f.set(ret, fromJsonString(f.getType(), valueJsonString));
        }
        return (T) ret;
    }

    public static String toJsonString(Object o) {
        try {
            return parseValue(o);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String parseValue(Object o) throws Exception {
        // 返回null, 可以根据返回值决定是否将该值加入json串, 默认为null不加入
        if (o == null) return null;

        Class<?> klass = o.getClass();
        // 先判断是否是原始类型
        if (isPrimitive(klass)) return String.valueOf(o);

        if (String.class.equals(klass)) {
            return new StringBuilder()
                    .append(quote)
                    .append(o.toString())
                    .append(quote)
                    .toString();
        }

        // 集合类
        if (Collection.class.isAssignableFrom(klass)) {
            StringBuilder sb = new StringBuilder();
            sb.append(arrayBegin);
            Collection c = (Collection) o;
            for (Object item : c) {
                String s = parseValue(item);
                if (s == null) continue; // 跳过null值
                else {
                    sb.append(s).append(delimiter);
                }
            }
            if (sb.charAt(sb.length() - 1) == delimiter) sb.deleteCharAt(sb.length() - 1);
            sb.append(arrayEnd);
            return sb.toString();
        }

        // 暂不支持Map

        // 普通POJO
        Field[] fs = o.getClass().getDeclaredFields();
        StringBuilder sb = new StringBuilder();
        sb.append(objectBegin);
        for (Field f : fs) {
            String fieldName = f.getName();
            f.setAccessible(true);
            Object fieldValue = f.get(o);
            String valueString = parseValue(fieldValue);
            if (valueString == null) continue; // 跳过null属性
            sb.append(quote).append(fieldName).append(quote).append(colon).append(valueString).append(delimiter);
        }
        if (sb.charAt(sb.length() - 1) == delimiter) sb.deleteCharAt(sb.length() - 1);
        sb.append(objectEnd);
        return sb.toString();
    }

    // 是否是原始类型(int, Integer)
    private static boolean isPrimitive(Class<?> klass) {
        if (klass.isPrimitive()) return true;
        try {
            Field f = klass.getField("TYPE");
            if (f != null) {
                Class<?> inClass = (Class<?>) f.get(null);
                return inClass.isPrimitive();
            }
        } catch (Exception e) {

        }
        return false;
    }

    private static boolean isNumeric(String s) {
        if (s == null || s.isEmpty()) return false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (i == 0 && (c == '+' || c == '-')) continue; // 正负
            if (!Character.isDigit(c)) return false; // 不是数字
        }
        return true;
    }

    public static Map<String, Object> convertToMap(char[] jsonCharArray) {
        String jsonString = new String(jsonCharArray);
        return parseJsonToMap(jsonString);
    }

    public static Map<String, Object> convertToMap(byte[] jsonCharArray) {
        String jsonString = new String(jsonCharArray);
        return parseJsonToMap(jsonString);
    }

    private static Map<String, Object> parseJsonToMap(String json) {
        Map<String, Object> result = new HashMap<>();
        // 假设json格式简单，例如：{"key1":"value1","key2":123}
        // 实际应用中需要处理更复杂的JSON结构
        int startIndex = json.indexOf('{') + 1;
        int endIndex = json.lastIndexOf('}');
        String content = json.substring(startIndex, endIndex);

        String[] keyValues = content.split(",");
        for (String keyValue : keyValues) {
            // 剔除不符合规则的数据
            if(!keyValue.contains(":")){
                continue;
            }
            String[] entry = keyValue.split(":");
            String key = entry[0].replaceAll("\"", "");
            String value = entry[1].replaceAll("\"", "");
            if (value.matches("^\\d+$")) {
                result.put(key, Integer.parseInt(value));
            } else {
                result.put(key, value);
            }
        }
        return result;
    }

    public static void main(String[] args) {
        char[] jsonCharArray = "{\"key1\":\"value1\",\"key2\":123}".toCharArray();
        Map<String, Object> map = convertToMap(jsonCharArray);
        System.out.println(map);
    }
}
